using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Ionic.Zip;
using Ionic.Zlib;

namespace Catastrophe.Common.Tools
{
	public class ZipUtil
	{
		public static bool CompressMulti(List<string> list, string strZipName, bool IsDirStruct)
		{
			try
			{
				using ZipFile zipFile = new ZipFile(Encoding.Default);
				foreach (string item in list)
				{
					string fileName = Path.GetFileName(item);
					if (Directory.Exists(item))
					{
						if (IsDirStruct)
						{
							zipFile.AddDirectory(item, fileName);
						}
						else
						{
							zipFile.AddDirectory(item);
						}
					}
					if (File.Exists(item))
					{
						zipFile.AddFile(item);
					}
				}
				zipFile.Save(strZipName);
				return true;
			}
			catch (Exception)
			{
				return false;
			}
		}

		public static bool Compress(string sourceFilePath, string targetFileFullPath, string password, int maxOutputSegmentSiez, out string errMessage)
		{
			try
			{
				using ZipFile zipFile = new ZipFile(Encoding.Default);
				errMessage = string.Empty;
				zipFile.Comment = "压缩文件时间" + DateTime.Now.ToString("G");
				zipFile.Name = Guid.NewGuid().ToString().ToUpper() + ".zip";
				if (!string.IsNullOrWhiteSpace(password))
				{
					zipFile.Password = password;
				}
				zipFile.MaxOutputSegmentSize = maxOutputSegmentSiez * 1000;
				zipFile.BufferSize = 1024;
				zipFile.CaseSensitiveRetrieval = true;
				zipFile.CompressionLevel = CompressionLevel.BestCompression;
				zipFile.AddDirectory(sourceFilePath);
				zipFile.Save(targetFileFullPath);
				return true;
			}
			catch (Exception ex)
			{
				errMessage = ex.Message;
				return false;
			}
		}

		public static bool Decompress(string strZipPath, string strUnZipPath, bool overWrite)
		{
			try
			{
				ReadOptions readOptions = new ReadOptions();
				readOptions.Encoding = Encoding.Default;
				using ZipFile zipFile = ZipFile.Read(strZipPath, readOptions);
				foreach (ZipEntry item in zipFile)
				{
					if (string.IsNullOrEmpty(strUnZipPath))
					{
						strUnZipPath = strZipPath.Split('.').First();
					}
					if (overWrite)
					{
						item.Extract(strUnZipPath, ExtractExistingFileAction.OverwriteSilently);
					}
					else
					{
						item.Extract(strUnZipPath, ExtractExistingFileAction.DoNotOverwrite);
					}
				}
				return true;
			}
			catch (Exception)
			{
				return false;
			}
		}

		public static bool Decompress(string sourceFileFullPath, string targetFolderPath, string password, out string errMessage)
		{
			try
			{
				Encoding uTF = Encoding.UTF8;
				errMessage = string.Empty;
				ReadOptions options = new ReadOptions
				{
					StatusMessageWriter = Console.Out,
					Encoding = uTF
				};
				using ZipFile zipFile = ZipFile.Read(sourceFileFullPath, options);
				if (!string.IsNullOrWhiteSpace(password))
				{
					zipFile.Password = password;
				}
				zipFile.AlternateEncoding = uTF;
				zipFile.ExtractAll(targetFolderPath, ExtractExistingFileAction.OverwriteSilently);
				return true;
			}
			catch (Exception ex)
			{
				errMessage = ex.Message;
				return false;
			}
		}

		public static MemoryStream GetUriZipFile(byte[] buf, string uri, string fileName)
		{
			Uri uri2 = new Uri(uri);
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(uri2.AbsolutePath);
			string fullName = Path.Combine(fileNameWithoutExtension, fileName);
			return ZipUtil.GetUriZipFile(buf, fullName);
		}

		public static MemoryStream GetUriZipFile(byte[] buf, string fullName)
		{
			MemoryStream zipStream = new MemoryStream(buf);
			MemoryStream memoryStream = new MemoryStream();
			using (ZipFile zipFile = ZipFile.Read(zipStream))
			{
				ZipEntry zipEntry = zipFile[fullName];
				zipEntry.Extract(memoryStream);
			}
			return memoryStream;
		}

		public static Dictionary<string, byte[]> GetUriZipFileMulti(byte[] buf, List<string> extNameAry, bool isContainDirectory = false, params string[] fileName)
		{
			MemoryStream zipStream = new MemoryStream(buf);
			Dictionary<string, byte[]> dictionary = new Dictionary<string, byte[]>();
			using (ZipFile zipFile = ZipFile.Read(zipStream))
			{
				string text = "";
				foreach (ZipEntry item in zipFile)
				{
					if (item.IsDirectory)
					{
						text = item.FileName;
						continue;
					}
					FileInfo fileInfo = new FileInfo(item.FileName);
					if ((extNameAry == null || extNameAry.Count <= 0 || !extNameAry.All((string x) => x.ToLower() != fileInfo.Extension.ToLower())) && (fileName == null || fileName.Length == 0 || !fileName.All((string x) => !item.FileName.Contains(x))))
					{
						MemoryStream memoryStream = new MemoryStream();
						item.Extract(memoryStream);
						byte[] array = new byte[item.UncompressedSize];
						Array.Copy(memoryStream.GetBuffer(), array, array.Length);
						string key = item.FileName;
						if (!isContainDirectory && text.Trim() != "")
						{
							key = item.FileName.Replace(text, "");
						}
						dictionary.Add(key, array);
					}
				}
			}
			return dictionary;
		}
	}
}
